<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "https://www.w3.org/TR/html4/loose.dtd">
<html lang="zh-CN"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta http-equiv="Content-Language" content="zh-CN"><link href="stylesheet.css" media="all" rel="stylesheet" type="text/css">
<title>字符类型</title>
<script> var _hmt = _hmt || []; (function() { var hm = document.createElement("script"); hm.src = "https://hm.baidu.com/hm.js?d286c55b63a3c54a1e43d10d4c203e75"; var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(hm, s); })(); </script>
</head><body class="SECT1">
<div>
<table summary="Header navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><th colspan="5" align="center" valign="bottom">PostgreSQL 8.2.3 中文文档</th></tr>
<tr><td width="10%" align="left" valign="top"><a href="datatype-money.html" accesskey="P">后退</a></td><td width="10%" align="left" valign="top"><a href="datatype.html">快退</a></td><td width="60%" align="center" valign="bottom">章8. Data Types</td><td width="10%" align="right" valign="top"><a href="datatype.html">快进</a></td><td width="10%" align="right" valign="top"><a href="datatype-binary.html" accesskey="N">前进</a></td></tr>
</table>
<hr align="LEFT" width="100%"></div>
<div class="SECT1"><h1 class="SECT1"><a name="DATATYPE-CHARACTER">8.3. 字符类型</a></h1><a name="AEN4218"></a><a name="AEN4221"></a><a name="AEN4224"></a><a name="AEN4226"></a><a name="AEN4228"></a><a name="AEN4230"></a><a name="AEN4232"></a>
<div class="TABLE"><a name="DATATYPE-CHARACTER-TABLE"></a>
<p><b>表8-4. 字符类型</b></p>
<table border="1" class="CALSTABLE"><col><col>
<thead>
<tr><th>名字</th><th>描述</th></tr>
</thead>
<tbody>
<tr><td><tt class="TYPE">character varying(<tt class="REPLACEABLE"><i>n</i></tt>)</tt>, <tt class="TYPE">varchar(<tt class="REPLACEABLE"><i>n</i></tt>)</tt></td><td>变长，有长度限制</td></tr>
<tr><td><tt class="TYPE">character(<tt class="REPLACEABLE"><i>n</i></tt>)</tt>, <tt class="TYPE">char(<tt class="REPLACEABLE"><i>n</i></tt>)</tt></td><td>定长，不足补空白</td></tr>
<tr><td><tt class="TYPE">text</tt></td><td>变长，无长度限制</td></tr>
</tbody>
</table>
</div>
<p><a href="datatype-character.html#DATATYPE-CHARACTER-TABLE">表8-4</a>显示了在 PostgreSQL 里可用于一般用途的字符类型。</p>
<p>SQL 定义了两种基本的字符类型：<tt class="TYPE">character varying(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> 和 <tt class="TYPE">character(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> ，这里的 <tt class="REPLACEABLE"><i>n</i></tt> 是一个正整数。两种类型都可以存储最多 <tt class="REPLACEABLE"><i>n</i></tt> 个字符的字符串。试图存储更长的字符串到这些类型的字段里会产生一个错误，除非超出长度的字符都是空白，这种情况下该字符串将被截断为最大长度。这个看上去有点怪异的例外是 SQL 标准要求的。如果要存储的字符串比声明的长度短，类型为 <tt class="TYPE">character</tt> 的数值将会用空白填满；而类型为 <tt class="TYPE">character varying</tt> 的数值将只是存储短些的字符串。</p>
<p>如果我们明确地把一个数值转换成 <tt class="TYPE">character varying(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> 或 <tt class="TYPE">character(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> ，那么超长的数值将被截断成 <tt class="REPLACEABLE"><i>n</i></tt> 个字符，且不会抛出错误。这也是 SQL 标准的要求。</p>
<p><tt class="TYPE">varchar(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> 和 <tt class="TYPE">char(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> 分别是 <tt class="TYPE">character varying(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> 和 <tt class="TYPE">character(<tt class="REPLACEABLE"><i>n</i></tt>)</tt>的别名，没有声明长度的 <tt class="TYPE">character</tt> 等于 <tt class="TYPE">character(1)</tt> ；如果不带长度说明词使用 <tt class="TYPE">character varying</tt>，那么该类型接受任何长度的字符串。后者是 PostgreSQL 的扩展。</p>
<p>另外，PostgreSQL 提供 <tt class="TYPE">text</tt> 类型，它可以存储任何长度的字符串。尽管类型 <tt class="TYPE">text</tt> 不是 SQL 标准，但是许多其它 SQL 数据库系统也有它。</p>
<p><tt class="TYPE">character</tt> 类型的数值物理上都用空白填充到指定的长度 <tt class="REPLACEABLE"><i>n</i></tt> 并且以这种方式存储和显示。不过，填充的空白在是无语意的。在比较两个 <tt class="TYPE">character</tt> 值的时候，填充的空白都不会被关注，在转换成其它字符串类型的时候，<tt class="TYPE">character</tt> 值里面的空白会被删除。请注意，在 <tt class="TYPE">character varying</tt> 和 <tt class="TYPE">text</tt> 数值里，结尾的空白是<span class="emphasis"><i class="EMPHASIS">有语意</i></span>的。</p>
<p>这些类型的存储需求是 4 字节加上实际的字符串，如果是 <tt class="TYPE">character</tt> 的话再加上填充的字节。长的字符串将会自动被系统压缩，因此在磁盘上的物理需求可能会更少些。长的数值也会存储在后台表里面，这样它们就不会干扰对短字段值的快速访问。不管怎样，允许存储的最长字符串大概是 1GB 。允许在数据类型声明中出现的 <tt class="REPLACEABLE"><i>n</i></tt> 的最大值比这还小。修改这个行为没有什么意义，因为在多字节编码下字符和字节的数目可能差别很大。如果你想存储没有特定上限的长字符串，那么使用 <tt class="TYPE">text</tt> 或没有长度声明词的 <tt class="TYPE">character varying</tt> ，而不要选择一个任意长度限制。</p>
<div class="TIP">
<blockquote class="TIP">
<p><b>【提示】</b>这三种类型之间没有性能差别，只不过是在使用 <tt class="TYPE">character</tt> 的时候增加了存储尺寸。虽然在某些其它的数据库系统里，<tt class="TYPE">character(<tt class="REPLACEABLE"><i>n</i></tt>)</tt> 有一定的性能优势，但在 PostgreSQL 里没有。在大多数情况下，应该使用 <tt class="TYPE">text</tt> 或 <tt class="TYPE">character varying</tt> 。</p>
</blockquote>
</div>
<p>请参考<a href="sql-syntax-lexical.html#SQL-SYNTAX-STRINGS">节4.1.2.1</a>获取关于字符串文本的语法的信息，以及<a href="functions.html">章9</a>获取关于可用操作符和函数的信息。数据库的字符集决定用于存储文本值的字符集；有关字符集支持的更多信息，请参考<a href="multibyte.html">节21.2</a>。</p>
<div class="EXAMPLE"><a name="AEN4323"></a>
<p><b>例8-1. 使用字符类型</b></p>
<pre class="PROGRAMLISTING">CREATE TABLE test1 (a character(4));
INSERT INTO test1 VALUES ('ok');
SELECT a, char_length(a) FROM test1;
<samp class="COMPUTEROUTPUT">  a   | char_length
------+-------------
 ok   |           2</samp>

CREATE TABLE test2 (b varchar(5));
INSERT INTO test2 VALUES ('ok');
INSERT INTO test2 VALUES ('good      ');
INSERT INTO test2 VALUES ('too long');
<samp class="COMPUTEROUTPUT">ERROR:  value too long for type character varying(5)</samp>
INSERT INTO test2 VALUES ('too long'::varchar(5)); -- 明确截短
SELECT b, char_length(b) FROM test2;
<samp class="COMPUTEROUTPUT">   b   | char_length
-------+-------------
 ok    |           2
 good  |           5
 too l |           5</samp></pre>
<div class="CALLOUTLIST">
<p><code class="FUNCTION">char_length</code> 函数在<a href="functions-string.html">节9.4</a>中讨论。</p>
</div>
</div>
<p>在 PostgreSQL 里另外还有两种定长字符类型。在<a href="datatype-character.html#DATATYPE-CHARACTER-SPECIAL-TABLE">表8-5</a>里显示。<tt class="TYPE">name</tt> 类型<span class="emphasis"><i class="EMPHASIS">只</i></span>用于在内部系统表中存储标识符并且不是给一般用户使用的。该类型长度当前定为 64 字节(63 可用字符加结束符)但应该使用常量 <tt class="SYMBOL">NAMEDATALEN</tt> 引用。这个长度是在编译的时候设置的，因而可以为特殊用途调整，缺省的最大长度在以后的版本可能会改变。类型 <tt class="TYPE">"char"</tt>(注意引号)和 <tt class="TYPE">char(1)</tt> 是不一样的，它只用了一个字节的存储空间。它在系统内部用于系统表当做穷人的枚举类型用。</p>
<div class="TABLE"><a name="DATATYPE-CHARACTER-SPECIAL-TABLE"></a>
<p><b>表8-5. 特殊字符类型</b></p>
<table border="1" class="CALSTABLE"><col><col><col>
<thead>
<tr><th>名字</th><th>存储空间</th><th>描述</th></tr>
</thead>
<tbody>
<tr><td><tt class="TYPE">"char"</tt></td><td>1 字节</td><td>单字节内部类型</td></tr>
<tr><td><tt class="TYPE">name</tt></td><td>64 字节</td><td>用于对象名的内部类型</td></tr>
</tbody>
</table>
</div>
</div>
<div>
<hr align="LEFT" width="100%">
<table summary="Footer navigation table" width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td width="33%" align="left" valign="top"><a href="datatype-money.html" accesskey="P">后退</a></td><td width="34%" align="center" valign="top"><a href="index.html" accesskey="H">首页</a></td><td width="33%" align="right" valign="top"><a href="datatype-binary.html" accesskey="N">前进</a></td></tr>
<tr><td width="33%" align="left" valign="top">货币类型</td><td width="34%" align="center" valign="top"><a href="datatype.html" accesskey="U">上一级</a></td><td width="33%" align="right" valign="top">二进制数据类型</td></tr>
</table>
</div>
</body></html>